package com.unittec.drainage.provider.config;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.unittec.drainage.provider.common.RabbitConstants;
import com.unittec.drainage.provider.scope.GlobalScope;
import com.unittec.drainage.provider.ApplicationContextProvider;
import com.unittec.drainage.provider.log.Log;
import com.unittec.drainage.sdk.root.internal.utils.SdkUtils;
import com.unittec.drainage.sdk.log.request.Req102011;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Headers;

import java.util.Map;

/**
 * @author wuxinwei
 *
 */
@ConditionalOnProperty(value = "spring.rabbitmq.host")
@Configuration
public class MqueueConfig {

    @Autowired
    private Log log;

    @Value("${spring.application.name}")
    private String queueName;

    /**
     * 由于业务服务会集群部署，需要声明广播类型的交换器，日志服务发布的日志级别更新消息所有服务都能接收到
     *
     * @return
     */
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(RabbitConstants.EXCHANGE_FANOUT);
    }

    @Bean
    public Queue queueLogLevel() {
        // 队列持久
        return new Queue(queueName, true);
    }

    @Bean
    public Binding bindingLogLevel() {
        return BindingBuilder.bind(queueLogLevel()).to(fanoutExchange());
    }

    @RabbitListener(queues = "${spring.application.name}")
    public void process(Req102011 content, Channel channel, @Header(name = "amqp_deliveryTag") long deliveryTag,
        @Header("amqp_redelivered") boolean redelivered, @Headers Map<String, String> head) {
        try {
            System.out.println("MQ   process content" + JSON.toJSON(content));
            // 消息是广播的，需要判断是否是自己的消息
            if (content.getServiceId().equalsIgnoreCase(ApplicationContextProvider.getAppName())) {
                GlobalScope.setLogLevel(content.getAppId(), content.getLogLevel());
                System.out.println("MQ   process content  修改成功");
            }
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            log.sysErrLog("91301", SdkUtils.toJSON(content), e);
            // 一般重试肯定的有次数，这里简单的根据是否已经重发过来来决定重发。第二个参数表示是否重新分发
            try {
                channel.basicReject(deliveryTag, !redelivered);
            } catch (Exception e1) {
            }
        }
    }
}
